// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

// Adiciona máscara para ano
jQuery.mask.masks.year = {mask: '9999'};
jQuery.mask.masks.integer_allow_zero = jQuery.mask.masks.integer;

// Configura todos os campos que requerem máscara ao carregar documento
jQuery(function() {
  jQuery('form:has(:text[alt=decimal])').fixDecimalInputs();
  jQuery('form:has(:text[alt=integer],:text[alt=integer_allow_zero])').fixIntegerInputsOnSubmit();
  jQuery(':text[alt]').setDefaultMask();
});

// Seta máscara e redefine defaultValue
jQuery.fn.setDefaultMask = function() {
  return this.setMask().each(function() {
    this.defaultValue = this.value;
  }).keyup();
};

jQuery.fn.fixDecimalInputs = function() {
  this.submit(formDecimalToUsDecimal);
  this.find(':text[alt=decimal]').each(usToPtDecimal);
  return this;
}

jQuery.fn.fixIntegerInputsOnBlur = function() {
  this.find(':text[alt=integer]').blur(ptToUsIntegerAjax);
  return this;
}

jQuery.fn.fixIntegerInputsOnSubmit = function() {
  this.submit(formIntegerToUsInteger);
  return this;
}

function formDecimalToUsDecimal() {
  jQuery(this).find(':text[alt=decimal]').each(ptToUsDecimal);
}

function formIntegerToUsInteger() {
  jQuery(this).find(':text[alt=integer],:text[alt=integer_allow_zero]').each(ptToUsInteger);
}

// Converte valor de campo com número decimal para pt-br
function usToPtDecimal() {
  jQuery(this).val(parseFloat(this.value || 0).toFixed(2).replace(/\./g, '\,'));
}

// Desformata valor de campo com número decimal em pt-br
function ptToUsDecimal() {
  this.value = unformatPtDecimal(this.value);
}

// Desformata valor de campo com número inteiro em pt-br
function ptToUsInteger() {
  this.value = unformatPtInteger(this.value);
  if(this.value == "" && this.alt == "integer_allow_zero") this.value = 0;
}

// Desformata valor de campo com número inteiro em pt-br nos campos ajax
function ptToUsIntegerAjax() {
  if (this.value != this.defaultValue)
    jQuery(this).each(ptToUsInteger);
}

// Transforma string em pt-br para float
function parseFloatPt(value) {
  return parseFloat(unformatPtDecimal(value)) || 0;
}

// Transforma string em pt-br para int
function parseIntPt(value) {
  return parseInt(unformatPtInteger(value)) || 0;
}

// Desformata float em pt-br
function unformatPtDecimal(value) {
  if(value && value.constructor == String)
    value = value.replace(/\./g, '').replace(/\,/, '\.');
  return value;
}

// Desformata int em pt-br
function unformatPtInteger(value) {
  if(value && value.constructor == String)
    value = value.replace(/\./g, '').replace(/^0+/, "");
  return value;
}

jQuery.fn.hideAndRemove = function() {
  this.fadeOut("slow", function() {jQuery(this).remove()});
  return this;
};

// Configura jQuery para trabalhar com Ajax
jQuery.ajaxSetup({
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});

// Funções para controlar o css nos forms
function setErrorState(form) { form.find(':text').css('background-color', 'Pink'); }
function setSubmittingState(form) { form.find(':text').css('background-color', 'Khaki'); }
function setSuccessState(form) { form.find(':text').css('background-color', 'LightGreen'); }
function unsetState(form) { form.find(':text').css('background-color', ''); }

// Configura form para ser submetido via Ajax
jQuery.fn.submitWithAjax = function(validationFunction) {
  function ajaxSubmitHandler() {
    var form = jQuery(this);

    var valido = validationFunction ? validationFunction(form) : true;
    if(!valido)
      return false;
    jQuery.ajax({
      url: this.action,
      type: 'POST',
      data: form.serialize(),
      dataType: 'script',
      beforeSend: function(){setSubmittingState(form)},
      success: function(){setSuccessState(form)},
      error: function(){setErrorState(form)},
      complete: null
    });
    return false;
  }

  // TODO checar se ja tem o handler pra nao chamar 2 vezes
  this.submit(ajaxSubmitHandler);

  return this;
};

jQuery.fn.isDirty = function() {
  var form = this.get(0);
  for (var i = 0; i < form.elements.length; i++) {
    var element = form.elements[i];
    var type = element.type;
    if (type == "checkbox" || type == "radio") {
      if (element.checked != element.defaultChecked)
        return true;
    } else if (type == "hidden" || type == "password" || type == "text" || type == "textarea") {
      if (element.value != element.defaultValue)
        return true;
    } else if (type == "select-one" || type == "select-multiple") {
      for (var j = 0; j < element.options.length; j++) {
        if (element.options[j].selected != element.options[j].defaultSelected)
          return true;
      }
    }
  }
  return false;
};

// Guardam a fila dos forms submetidos com ajax
LAST_FOCUSED_FORM_ID = null;
PENDING_FORMS = {};

// Submete os formulários que estiverem na fila
var checkFormChanged = function() {
  for(var formId in PENDING_FORMS) {
    if(formId == LAST_FOCUSED_FORM_ID)
      continue;
    var form = jQuery('#'+formId);
    if(form.isDirty())
      form.triggerHandler('submit');
    delete PENDING_FORMS[formId];
  }
}

// Configura form para ser editado in-place
jQuery.fn.editInPlace = function(validationFunction) {
  this.submitWithAjax(validationFunction);

  // avisa usuário se há forms pendentes antes de sair da página
  if(window.onbeforeunload == undefined) {
    window.onbeforeunload = function() {
      var hasItems = false;
      for(var formId in PENDING_FORMS) {
        hasItems = true;
        break;
      }
      if(hasItems)
        return 'Alguns dados ainda não foram salvos e podem ser perdidos.';
    };
  }

  var inputs = this.find(':text');
  inputs.each(function () {
    var element = jQuery(this);

    element.focus(function() {
      var form = jQuery(this.form);
      LAST_FOCUSED_FORM_ID = this.form.id;
      form.addClass('editing');
      element.select();
    });

    element.blur(function(event) {
      LAST_FOCUSED_FORM_ID = null;
      var form = jQuery(this.form);
      form.removeClass('editing');
      setTimeout(checkFormChanged, 500);
      if (this.value != this.defaultValue)
        PENDING_FORMS[this.form.id] = true;
    });
  });

  return this;
};

// Configura form para ser removido in-place
jQuery.fn.removeInPlace = function(modelName) {
  var delete_button = this.find("input[id*=remove_"+modelName+"]");
  delete_button.click(function() {
    var form = jQuery(this.form);
    if(form.hasClass("new_"+modelName))
      form.hideAndRemove();
    else
      form.find(':text').val('').change().blur();
  });
  return this;
}

/*
 * Adiciona '\\' antes de '[' e ']' pra o jQuery funcionar com os inputs do rails
 */
function jq (selector) {
  return selector.replace(/(\[|\])/g, '\\$1');
}

/*
 * Valida email
 */
function isEmail (email) {
  var regex = /^[a-zA-Z0-9._-]{1,32}@([a-zA-Z0-9_-]{1,20}\.[a-zA-Z0-9_-]{1,32})(\.[a-zA-Z0-9_-]{1,32})*$/;
  return regex.test(email);
}

/**
 * Adiciona método lpad() à classe String.
 * Preenche a String à esquerda com o caractere fornecido,
 * até que ela atinja o tamanho especificado.
 */
String.prototype.lpad = function(pSize, pCharPad) {
  var str = this;
  var dif = pSize - str.length;
  var ch = String(pCharPad).charAt(0);
  for (; dif>0; dif--) str = ch + str;
  return (str);
} //String.lpad

/**
 * Adiciona método trim() à classe String.
 * Elimina brancos no início e fim da String.
 */
String.prototype.trim = function() {
  return this.replace(/^\s*/, "").replace(/\s*$/, "");
} //String.trim

function enableField (selector) {
  return jQuery(selector).attr('disabled', '');
}

function disableField (selector) {
  return jQuery(selector).attr('disabled', 'disabled');
}

jQuery.fn.disable = function() {
  return this.attr('disabled', true);
}

jQuery.fn.enable = function() {
  return this.attr('disabled', false);
}

// Calculando o TOTAL da tabela automaticamente

var getFieldsByToken = function(container, token) {
  return jQuery(container).find(':text[id*='+token+']');
};

var getTotalRowByToken = function(container, token) {
  return jQuery(container).find('input[name=total_'+token+']');
};

var calculateTotalByToken = function(container, token) {
  var fields = getFieldsByToken(container, token);
  var totalRow = getTotalRowByToken(container, token);
  var isDecimal = totalRow.attr('alt') == 'decimal'
  var total = 0;

  fields.each(function() {
    var input = jQuery(this);
    var inputValue = input.val();
    if(isDecimal)
      inputValue = parseFloatPt(inputValue);
    else
      inputValue = parseIntPt(inputValue);
    total += inputValue;
  });

  if(isDecimal)
    total = total.toFixed(2);
  totalRow.val(total);
  totalRow.keyup();
};

var extractYearFromId = function(inputId) {
  var match = inputId.match(/(\d{4})/);
  return match ? match[0] : '';
};

// Zebra tables
jQuery(function() {
  jQuery("table.lines tbody tr:nth-child(odd)").addClass("odd");
});
